-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
support drm init data per discontinuity #4180
base: dev-v2
Are you sure you want to change the base?
Conversation
@@ -358,7 +358,7 @@ public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, long l | |||
isTimestampMaster, | |||
timestampAdjuster, | |||
previous, | |||
mediaPlaylist.drmInitData, | |||
mediaPlaylist.drmInitData.get(segment.relativeDiscontinuitySequence), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think more than one drm init data can map to a single discontinuity sequence.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for taking a look at this pr.
more than one drm init data can map to a single discontinuity sequence
I coundn’t think of the situation of multiple init data in a single discontinuity sequence
Could you tell me how the playlist look like?
Do you mean we have to apply drmInitData until the next #EXT-X-KEY
or the end of the playlist?
And one more thing.
As you explained here, you don’t want to use SparseArray?
If so, how do you want me to implement it?
313fb2b
to
658960f
Compare
@AquilesCanta |
Hi @TakuSemba, thanks for the PR. Will look into this as soon as I have some time, I promise. Hopefully we can get it pulled from. Sorry for the delay. |
@@ -42,6 +42,11 @@ | |||
* used for all segments that share an EXT-X-MAP tag. | |||
*/ | |||
@Nullable public final Segment initializationSegment; | |||
/** | |||
* DRM initialization data for sample decryption, or null if none of the segment uses sample |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably be changed to
{@link DrmInitData} for sample decryption, or null if the segment's samples are not DRM-protected.
@@ -81,7 +86,7 @@ | |||
* @param byterangeLength See {@link #byterangeLength}. | |||
*/ | |||
public Segment(String uri, long byterangeOffset, long byterangeLength) { | |||
this(uri, null, 0, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength, false); | |||
this(uri, null, null, 0, -1, C.TIME_UNSET, null, null, byterangeOffset, byterangeLength, false); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit (not sure it applies): Lines should not exceed 100 chars.
@@ -17,6 +17,7 @@ | |||
|
|||
import android.net.Uri; | |||
import android.util.Base64; | |||
import android.util.SparseArray; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a stray import?
@@ -424,15 +425,16 @@ private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String | |||
} else if (method != null) { | |||
SchemeData schemeData = parseWidevineSchemeData(line, keyFormat); | |||
if (schemeData != null) { | |||
drmInitData = | |||
new DrmInitData( | |||
drmInitData = new DrmInitData( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we leave this as before?
@@ -360,7 +360,7 @@ public void getNextChunk(HlsMediaChunk previous, long playbackPositionUs, long l | |||
isTimestampMaster, | |||
timestampAdjuster, | |||
previous, | |||
mediaPlaylist.drmInitData, | |||
segment.drmInitData, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is an issue with this: If the first segment is not encrypted, then the media chunk will expose no DRM init data, and the track selector will think the segment is not encrypted. I'll try to think about a solution for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I coundn't understand your concern.
I know the fact that shaka-packager creates a playlist like ↓ for a Widevine-encrypted content.
In that case, I believe that video_1.m4s is not (and should not be) encrypted and video_2.m4s ~ are encrypted with Widevine.
I think the track selector should think the segment is not encrypted, because it's not encrypted. 🤔
#EXTM3U
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:18
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-MAP:URI="video_init.mp4"
#EXTINF:13.583,
video_1.m4s
#EXT-X-DISCONTINUITY
#EXT-X-KEY:METHOD=SAMPLE-AES-CTR,URI="data:text/…
#EXTINF:10.417,
video_2.m4s
#EXTINF:7.417,
video_3.m4s
…
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The track selector does not know about specific segments, but rather about tracks. The issue is that the track is indeed encrypted (even if some of the segments are clear), but the first segment's format (unencrypted), as things are now, will be propagated as the track's format.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the replay! I understood what you mean.
will be propagated as the track's format.
but, I could not find the exact place where the track selector thinks the segment is not encrypted or a wrong track's format is propagated.
you want to me to fix it on this PR?
I'm sorry to bother you, but it would be really appreciated if you could tell me the specific point where it's happening.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What I suspect might be a solution for this is keeping a DrmInitData in the media playlist which contains SchemeData's with null SchemeData#data, so as to signal that encryption of a specific CDM is eventually there, without tying it to a specific key/pssh. This DrmInitData would then be propagated by the period for the track selector to consume. This field would be populated by the playlist parser after parsing all EXT-X-KEYS present in the playlist.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure about what you suggest.
Does your suggestion mean HlsMediaPlaylist should hold a single DrmInitData with null SchemeData#data? (Instead of letting each segment hold a DrmInitData)
and again, Im playing the content, which has the first non-encrypted segment and the other widevine-encrypted segments, and It plays without any problems, and could not find the place where wrong track's formats are created or propagated while breakpointing inside exoplayer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does your suggestion mean HlsMediaPlaylist should hold a single DrmInitData with null SchemeData#data
No, it should contain as many scheme datas as encryption schemes there are in the content. For example, if the media is encrypted using both Widevine and Playready, in would contain two SchemeDatas, one for each.
Im playing the content, which has the first non-encrypted segment and the other widevine-encrypted segments
This issue does not affect playback. We have a similar problem to the one introduced here in chunkless preparation (but unlike here, we cannot do much without downloading extra stuff, which defeats the purpose of chunkless preparation).
The issue is track selection. The tracks exposed by the MediaPeriod will not contain DRM data, so the track selector will assume the content is unencrypted. The resulting behavior is a crash instead of graceful handling of unsupported DRM schemes. In this case, you are playing on a device that supports the used DRM scheme. If it didn't, the player would crash instead (potentially -though rare- with a native crash). Hopefully this is clear.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the explanation!.
The tracks exposed by the MediaPeriod will not contain DRM data
I think the place where the MediaPeriod exposes the tracks is here.
But, it seems like the MediaPeriod has the track groups with non-null drmInitData in it.
http://160.16.54.236:8081/drmtest/media/drm/180p/master.m3u8 is the stream that I tested .
{
"name": "HLS Plain (180p)",
"uri": "http://160.16.54.236:8081/drmtest/media/plain/180p/master.m3u8"
},
{
"name": "HLS DRM (180p)",
"uri": "http://160.16.54.236:8081/drmtest/media/drm/180p/master.m3u8",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy"
},
{
"name": "HLS Plain (180p) -> DRM (180p)",
"uri": "http://160.16.54.236:8081/drmtest/playlist/plain180p-drm180p/master.m3u8",
"drm_scheme": "widevine",
"drm_license_url": "https://proxy.uat.widevine.com/proxy"
},
And your solution is not clear to me yet.
keeping a DrmInitData in the media playlist which contains SchemeData's with null SchemeData#data
does your suggestion mean keeping an another DrmInitData only for the first segment like ↓?
private static HlsMediaPlaylist parseMediaPlaylist(LineIterator iterator, String baseUri)
throws IOException {
...
String encryptionKeyUri = null;
String encryptionIV = null;
DrmInitData drmInitData = null;
DrmInitData drmInitDataforFirstSegment = // drmInitData which contains SchemeData's with null SchemeData#data;
String line;
while (iterator.hasNext()) {
line = iterator.next();
...
}
}
Also add support for parsing PlayReady DRM information Issue:#4180 ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=208094290
Im trying to play a HLS content, which has a DRM content and a non-DRM content separated by
#EXT-X-DISCONTINUITY
, it seems like ExoPlayer uses secure decoder even when playing non-DRM content.I think it is because ExoPlayer holds a single
drmInitData
.I fixed to let ExoPlayer have
drmInitData
per#EXT-X-DISCONTINUITY
, and I confirmed ExoPlayer switches decoder between a DRM content and a non-DRM content.You can use the hls url that I prepared, but this would only work after successfully these my pull requests merged.
I hope this pr would be acceptable.